from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Text, Boolean, Float, JSON
from sqlalchemy.orm import relationship
from datetime import datetime
from enum import Enum
from server.db.base import BaseModel

class ServerStatus(str, Enum):
    """服务器状态枚举"""
    STOPPED = "stopped"
    RUNNING = "running"
    STARTING = "starting"
    STOPPING = "stopping"
    ERROR = "error"
    BACKING_UP = "backing_up"
    RESTORING = "restoring"

class ServerType(str, Enum):
    """服务器类型枚举"""
    DEDICATED = "dedicated"
    LOCAL = "local"
    CLOUD = "cloud"

class Server(BaseModel):
    __tablename__ = 'servers'

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String(100), nullable=False, comment='服务器名称')
    description = Column(Text, nullable=True, comment='服务器描述')
    type = Column(String(20), default=ServerType.DEDICATED.value, comment='服务器类型')
    ip = Column(String(50), nullable=False, comment='服务器IP地址')
    port = Column(Integer, default=8211, comment='游戏端口')
    rcon_port = Column(Integer, default=25575, comment='RCON端口')
    rcon_password = Column(String(50), nullable=False, comment='RCON密码')
    max_players = Column(Integer, default=32, comment='最大玩家数')
    game_version = Column(String(20), nullable=True, comment='游戏版本')
    status = Column(String(20), default=ServerStatus.STOPPED.value, comment='服务器状态')
    install_path = Column(String(255), nullable=False, comment='安装路径')
    executable_path = Column(String(255), nullable=True, comment='可执行文件路径')
    steam_app_id = Column(Integer, default=2394010, comment='Steam应用ID')
    steam_branch = Column(String(50), default='public', comment='Steam分支')
    auto_start = Column(Boolean, default=False, comment='是否开机自启')
    created_by = Column(Integer, ForeignKey('users.id'), nullable=False, comment='创建者ID')
    last_start_time = Column(DateTime, nullable=True, comment='最后启动时间')
    last_stop_time = Column(DateTime, nullable=True, comment='最后停止时间')
    cpu_limit = Column(Float, nullable=True, comment='CPU限制(核心数)')
    memory_limit = Column(Integer, nullable=True, comment='内存限制(MB)')
    bandwidth_limit = Column(Integer, nullable=True, comment='带宽限制(Kbps)')
    is_public = Column(Boolean, default=False, comment='是否公开服务器')
    public_description = Column(Text, nullable=True, comment='公开服务器描述')
    public_image = Column(String(255), nullable=True, comment='公开服务器图片')

    # 关系
    configs = relationship('ServerConfig', back_populates='server', cascade='all, delete-orphan')
    backups = relationship('ServerBackup', back_populates='server', cascade='all, delete-orphan')
    mods = relationship('ServerMod', back_populates='server', cascade='all, delete-orphan')
    logs = relationship('ServerLog', back_populates='server', cascade='all, delete-orphan')
    status_history = relationship('ServerStatusHistory', back_populates='server', cascade='all, delete-orphan')
    created_user = relationship('User', foreign_keys=[created_by])

    def is_running(self) -> bool:
        """检查服务器是否正在运行"""
        return self.status == ServerStatus.RUNNING.value

    def can_start(self) -> bool:
        """检查服务器是否可以启动"""
        return self.status in [ServerStatus.STOPPED.value, ServerStatus.ERROR.value]

    def can_stop(self) -> bool:
        """检查服务器是否可以停止"""
        return self.status == ServerStatus.RUNNING.value

    def can_restart(self) -> bool:
        """检查服务器是否可以重启"""
        return self.status == ServerStatus.RUNNING.value

    def can_backup(self) -> bool:
        """检查服务器是否可以备份"""
        return self.status in [ServerStatus.RUNNING.value, ServerStatus.STOPPED.value]

class ServerConfig(BaseModel):
    __tablename__ = 'server_configs'

    id = Column(Integer, primary_key=True, index=True)
    server_id = Column(Integer, ForeignKey('servers.id', ondelete='CASCADE'), nullable=False, comment='服务器ID')
    config_key = Column(String(50), nullable=False, comment='配置键')
    config_value = Text(comment='配置值')
    is_custom = Column(Boolean, default=False, comment='是否自定义配置')
    category = Column(String(50), default='general', comment='配置类别')
    description = Column(Text, nullable=True, comment='配置描述')

    # 关系
    server = relationship('Server', back_populates='configs')

    __table_args__ = (
        {'unique_constraint': ('server_id', 'config_key')},
    )

class ServerStatusHistory(BaseModel):
    __tablename__ = 'server_status_history'

    id = Column(Integer, primary_key=True, index=True)
    server_id = Column(Integer, ForeignKey('servers.id', ondelete='CASCADE'), nullable=False, comment='服务器ID')
    old_status = Column(String(20), nullable=False, comment='旧状态')
    new_status = Column(String(20), nullable=False, comment='新状态')
    duration = Column(Integer, nullable=True, comment='持续时间(秒)')
    changed_by = Column(Integer, ForeignKey('users.id'), nullable=True, comment='变更者ID')
    comment = Column(Text, nullable=True, comment='备注')

    # 关系
    server = relationship('Server', back_populates='status_history')
    user = relationship('User')

class ServerMod(BaseModel):
    __tablename__ = 'server_mods'

    id = Column(Integer, primary_key=True, index=True)
    server_id = Column(Integer, ForeignKey('servers.id', ondelete='CASCADE'), nullable=False, comment='服务器ID')
    mod_id = Column(String(50), nullable=False, comment='模组ID')
    name = Column(String(100), nullable=False, comment='模组名称')
    version = Column(String(20), nullable=True, comment='模组版本')
    file_path = Column(String(255), nullable=True, comment='本地文件路径')
    workshop_id = Column(String(50), nullable=True, comment='Steam Workshop ID')
    enabled = Column(Boolean, default=True, comment='是否启用')
    load_order = Column(Integer, default=0, comment='加载顺序')
    hash = Column(String(128), nullable=True, comment='文件哈希')
    size = Column(Integer, nullable=True, comment='文件大小(字节)')

    # 关系
    server = relationship('Server', back_populates='mods')

    __table_args__ = (
        {'unique_constraint': ('server_id', 'mod_id')},
    )

class ServerBackup(BaseModel):
    __tablename__ = 'server_backups'

    id = Column(Integer, primary_key=True, index=True)
    server_id = Column(Integer, ForeignKey('servers.id', ondelete='CASCADE'), nullable=False, comment='服务器ID')
    backup_name = Column(String(100), nullable=False, comment='备份名称')
    backup_path = Column(String(255), nullable=False, comment='备份路径')
    size = Column(Integer, nullable=False, comment='备份大小(字节)')
    compression = Column(String(20), default='zstd', comment='压缩算法')
    version = Column(String(20), nullable=True, comment='游戏版本')
    status = Column(String(20), default='completed', comment='备份状态')
    duration = Column(Integer, nullable=True, comment='备份耗时(秒)')
    created_by = Column(Integer, ForeignKey('users.id'), nullable=False, comment='创建者ID')
    is_auto = Column(Boolean, default=False, comment='是否自动备份')
    retention_days = Column(Integer, default=7, comment='保留天数')
    checksum = Column(String(128), nullable=True, comment='校验和')

    # 关系
    server = relationship('Server', back_populates='backups')
    user = relationship('User')

class ServerLog(BaseModel):
    __tablename__ = 'server_logs'

    id = Column(Integer, primary_key=True, index=True)
    server_id = Column(Integer, ForeignKey('servers.id', ondelete='CASCADE'), nullable=False, comment='服务器ID')
    log_type = Column(String(20), default='console', comment='日志类型')
    log_level = Column(String(20), default='info', comment='日志级别')
    message = Column(Text, nullable=False, comment='日志消息')
    source = Column(String(50), nullable=True, comment='日志来源')
    player_id = Column(String(50), nullable=True, comment='玩家ID')
    player_name = Column(String(50), nullable=True, comment='玩家名称')
    ip_address = Column(String(50), nullable=True, comment='IP地址')
    details = Column(JSON, nullable=True, comment='详细信息')

    # 关系
    server = relationship('Server', back_populates='logs')

    __table_args__ = (
        {'indexes': [
            ('server_id', 'log_type'),
            ('server_id', 'log_level'),
            ('server_id', 'created_at')
        ]},
    )